package com.arpa.ntocc.common.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.arpa.ntocc.common.common.cache.DepartmentCache;
import com.arpa.ntocc.common.common.cache.DepartmentCacheDO;
import com.arpa.ntocc.common.common.util.CommonUtil;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.ntocc.common.domain.dto.DepartmentDTO;
import com.arpa.ntocc.common.domain.entity.Department;
import com.arpa.ntocc.common.domain.vo.DepartmentVO;
import com.arpa.ntocc.common.domain.vo.PartyGroupVO;
import com.arpa.ntocc.common.domain.vo.TreeData;
import com.arpa.ntocc.common.mapper.DepartmentMapper;
import com.arpa.ntocc.common.service.IDepartmentService;
import com.arpa.ntocc.common.service.IPartyGroupService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 部门信息 服务实现类
 * </p>
 *
 * @author LEO
 * @since 2019-12-09
 */
@Service
public class DepartmentServiceImpl extends ServiceImpl<DepartmentMapper, Department> implements IDepartmentService {

    @Autowired
    private IPartyGroupService iPartyGroupService;
    @Autowired
    @Lazy
    private DepartmentCache departmentCache;
    /**
     * 通过code查询用户
     * @param code
     * @return
     */
    @Override
    public Department getByCode(String code) {
        return baseMapper.selectOne(new QueryWrapper<Department>().lambda().eq(Department::getCode, code));
    }
    /**
     * 保存
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor={Exception.class})
    public boolean save(Department entity) {
        if(StringUtils.isBlank(entity.getCode())){
            entity.setCode(IdUtil.simpleUUID());
        }
        if(StringUtils.isBlank(entity.getCreatedBy())){
            entity.setCreatedBy(UserUtil.getCode());
        }
        departmentCache.flushAllByGroupCode(UserUtil.getBranchCode());
        return super.save(entity);
    }

    /**
     * 根据code更新实体
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor={Exception.class})
    public int updateByCode(Department entity) {
        if(StringUtils.isBlank(entity.getModifiedBy())){
            entity.setModifiedBy(UserUtil.getCode());
        }
        departmentCache.flushAllByGroupCode(UserUtil.getBranchCode());
        return baseMapper.update(entity,new QueryWrapper<Department>().lambda().eq(Department::getCode,entity.getCode()));
    }

    /**
     * 查询列表
     * @param departmentDTO
     * @return
     */
    @Override
    public List<DepartmentVO> queryList(DepartmentDTO departmentDTO){
        //排序字段名需要驼峰转数据库下划线类型字段名
        if(StringUtils.isNotEmpty(departmentDTO.getSortField())){
            departmentDTO.setSortField(CommonUtil.camel2Underline(departmentDTO.getSortField()));
        }
        List<DepartmentVO> departmentVOList = baseMapper.queryList(departmentDTO);
        return departmentVOList;
    }

    /**
     * 查询合计,包含总数
     * @param departmentDTO
     * @return
     */
    @Override
    public DepartmentVO queryListSum(DepartmentDTO departmentDTO){
        DepartmentVO departmentVO = baseMapper.queryListSum(departmentDTO);
        return departmentVO;
    }
    /**
     * 查询列表
     *
     * @param departmentDTO
     * @return
     */
    @Override
    public List<TreeData> queryTreeData(DepartmentDTO departmentDTO) {
        List<DepartmentCacheDO> departmentCacheDOS = departmentCache.getAllByPartyGroupCode(departmentDTO.getPartyGroupCode());
        List<TreeData> treeData = departmentCacheDOS.stream()
                .filter(r -> StringUtils.equalsIgnoreCase(r.getParentCode(), null))
                .map(
                r -> {
                    TreeData treeDataVO = new TreeData();
                    treeDataVO.setValue(r.getCode());
                    treeDataVO.setLabel(r.getName());
                    treeDataVO.setSpread(true);
                    treeDataVO.setChildren(selectDepartChildren(r.getCode(), departmentCacheDOS));
                    return treeDataVO;
                }
        ).collect(Collectors.toList());

        return treeData;
    }
    /**
     * 获取子级
     * 递归构建树
     *
     * @param parentdepartmentId
     * @return
     */
    private List<TreeData> selectDepartChildren(String parentdepartmentId, final List<DepartmentCacheDO> departmentCacheDOS) {
        List<TreeData> treeData = departmentCacheDOS.stream()
                .filter(r -> StringUtils.equalsIgnoreCase(r.getParentCode(), parentdepartmentId))
                .map(r -> {
                    TreeData treeData1 = new TreeData();
                    treeData1.setValue(r.getCode());
                    treeData1.setLabel(r.getName());
                    treeData1.setSpread(true);
                    if (selectDepartChildren(r.getCode(), departmentCacheDOS).size() == 0) {
                        return treeData1;
                    } else {
                        treeData1.setChildren(selectDepartChildren(r.getCode(), departmentCacheDOS));
                    }
                    return treeData1;
                }).collect(Collectors.toList());
        return treeData;
    }
    /**
     * 机构部门级联数据
     * @return
     */
    @Override
    public List<TreeData> cascadeData() {
        List<PartyGroupVO> partyGroups = null;
        List<TreeData> cascadeData = partyGroups.stream().map(r ->{
            DepartmentDTO departmentDTO = new DepartmentDTO();
            departmentDTO.setPartyGroupCode(r.getCode());
            List<DepartmentVO> departmentVOS =queryList(departmentDTO);

            TreeData treeDataVO = new TreeData();
            treeDataVO.setValue(r.getCode());
            treeDataVO.setLabel(r.getGroupName());
            treeDataVO.setSpread(true);
            List<TreeData> children = selectChildren(departmentVOS,r.getCode());
            if(children!=null &&children.size()>0) {
                treeDataVO.setChildren(children);
            }
            return treeDataVO;
        }).filter(s-> s.getChildren()!=null&&s.getChildren().size()>0).collect(Collectors.toList());

        return cascadeData;
    }

    /**
     * 机构部门级联数据不包括集团
     * @return
     */
    @Override
    public List<TreeData> cascadeDataNotLevel0() {


        List<PartyGroupVO> partyGroups = null;
        List<TreeData> cascadeData = partyGroups.stream().map(r ->{
            DepartmentDTO departmentDTO = new DepartmentDTO();
            departmentDTO.setPartyGroupCode(r.getCode());
            List<DepartmentVO> departmentVOS =queryList(departmentDTO);

            TreeData treeDataVO = new TreeData();
            treeDataVO.setValue(r.getCode());
            treeDataVO.setLabel(r.getGroupName());
            treeDataVO.setSpread(true);
            List<TreeData> children = selectChildren(departmentVOS,r.getCode());
            if(children!=null &&children.size()>0) {
                treeDataVO.setChildren(children);
            }
            return treeDataVO;
        }).filter(s-> s.getChildren()!=null&&s.getChildren().size()>0).collect(Collectors.toList());

        return cascadeData;
    }

    /**
     * 获取子级
     * 递归构建树
     * @param departmentVOS
     * @param partyGroupCode
     * @return
     */
    private List<TreeData> selectChildren(List<DepartmentVO> departmentVOS,String partyGroupCode) {

        List<TreeData> children= departmentVOS.stream().filter(r-> StrUtil.equalsIgnoreCase(partyGroupCode, r.getPartyGroupCode())).map(r->{
            TreeData treeData1 = new TreeData();
            treeData1.setValue(r.getCode());
            treeData1.setLabel(r.getName());
            treeData1.setSpread(true);
            return treeData1;
        }).collect(Collectors.toList());

        return   children;
    }

    /**
     *获取机构下的部门列表
     * @param groupCode
     * @return
     */
    @Override
    public List<DepartmentVO> getDepartmentList(String groupCode){
        List<Department> departmentList = this.list(new LambdaQueryWrapper<Department>().eq(Department::getPartyGroupCode, groupCode));
        return departmentList.stream().map(info -> {
            DepartmentVO departmentVO = new DepartmentVO();
            BeanUtil.copyProperties(info, departmentVO);
            return departmentVO;
        }).collect(Collectors.toList());
    }



}
